Deploying Dockerized Applications
This section covers how to deploy Dockerized applications using various methods. We'll cover:
- Using Docker Compose to Manage Multi-Container Applications
- Deployment Using Pre-built Docker Hub Images
- Building and Running an Image from a Dockerfile
- Deploying Flask with MySQL, Gunicorn, and Nginx (Detailed production-level deployment)
1. Using Docker Compose to Manage Multi-Container Applications
Scenario: You want to deploy a multi-container application using Docker Compose. In this case, we’ll start with a simple example of deploying an Nginx web server.
Directory Structure:
simple-nginx/
└── docker-compose.yml
docker-compose.yml:
version: '3'
services:
  web:
    image: nginx:alpine  # Pull a lightweight Nginx image from Docker Hub
    ports:
      - "8080:80"  # Map port 8080 on the host to port 80 in the container
Step-by-Step Explanation:
- image: nginx:alpine: We’re using the lightweight- nginx:alpineimage from Docker Hub.
- ports: "8080:80": This maps port- 8080on your local machine to port- 80inside the container (which is where Nginx serves its content). This allows you to access the Nginx web server through- http://localhost:8080.
How to Deploy:
- Create a directory called simple-nginx.
- Inside the directory, create a file called docker-compose.ymlwith the content above.
- Run the following command in the same directory:
docker compose up
- Open your browser and go to http://localhost:8080. You should see the default Nginx welcome page.
2. Deploying Flask Application with MySQL
Scenario: Deploying a simple Flask application that connects to a MySQL database using Docker Compose.
Directory Structure:
flask-mysql-app/
├── docker-compose.yml
└── flask-app/
    ├── Dockerfile
    ├── app.py
    ├── requirements.txt
docker-compose.yml:
version: '3'
services:
  web:
    build: ./flask-app  # Build the Flask app from the Dockerfile in the "flask-app" directory
    ports:
      - "5000:5000"  # Map port 5000 on the host to port 5000 inside the container
    environment:
      - FLASK_ENV=development
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: flask_db
      MYSQL_USER: user
      MYSQL_PASSWORD: userpassword
    ports:
      - "3306:3306"
Dockerfile:
# Use the official Python image
FROM python:3.8-slim
# Set the working directory
WORKDIR /app
# Copy current directory contents into /app
COPY . /app
# Install required Python packages
RUN pip install -r requirements.txt
# Command to run the Flask app
CMD ["python", "app.py"]
app.py:
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello():
    # Connect to the MySQL database
    db = mysql.connector.connect(
        host="db",  # This matches the MySQL service name in docker-compose
        user="user",
        password="userpassword",
        database="flask_db"
    )
    return "Connected to MySQL Database!"
if __name__ == "__main__":
    app.run(host='0.0.0.0')
requirements.txt:
Flask
mysql-connector-python
Step-by-Step Explanation:
- build: ./flask-app: We’re building a custom Flask application defined in the- Dockerfilelocated in the- flask-appdirectory.
- depends_on: db: Ensures that the- dbservice (MySQL) starts before the Flask app.
- MySQL Configuration: The dbservice is running a MySQL 5.7 container, with environment variables to configure the root password, database, and user credentials.
- Networking: Flask connects to the MySQL service using the hostname db, which is automatically set up by Docker Compose.
How to Deploy:
- Create the directory structure as shown above.
- Place the docker-compose.yml,Dockerfile,app.py, andrequirements.txtin their respective locations.
- Run:
docker compose up --build
- Visit http://localhost:5000to see your Flask app, which connects to the MySQL database.
3. Deploying Using Pre-built Docker Hub Images
Scenario: You want to quickly deploy a Redis server by pulling the official image from Docker Hub.
Directory Structure:
redis-server/
└── docker-compose.yml
docker-compose.yml:
version: '3'
services:
  redis:
    image: redis:latest  # Pull the official Redis image from Docker Hub
    ports:
      - "6379:6379"  # Map port 6379 on the host to port 6379 in the container
Step-by-Step Explanation:
- image: redis:latest: This pulls the latest Redis image from Docker Hub.
- ports: "6379:6379": This maps port- 6379on your host machine to port- 6379inside the container, which is the default Redis port.
How to Deploy:
- Create a directory called redis-server.
- Inside that directory, create a file called docker-compose.ymlwith the content above.
- Run:
docker compose up
- Redis will now be running, and you can interact with it at localhost:6379.
4. Advanced Scenario: Deploying Flask with MySQL, Gunicorn, and Nginx
Scenario: You want to deploy a production-ready Flask application that uses MySQL as the database, Gunicorn as the WSGI server, and Nginx as the reverse proxy.
Directory Structure:
flask-gunicorn-nginx/
├── docker-compose.yml
├── flask-app/
│   ├── Dockerfile
│   ├── app.py
│   ├── requirements.txt
└── nginx/
    └── nginx.conf
docker-compose.yml:
version: '3'
services:
  web:
    build: ./flask-app
    command: gunicorn -w 4 -b 0.0.0.0:5000 app:app
    expose:
      - "5000"
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: flask_db
      MYSQL_USER: user
      MYSQL_PASSWORD: userpassword
    ports:
      - "3306:3306"
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web
Dockerfile (Flask App):
# Use the official Python image
FROM python:3.8-slim
# Set the working directory
WORKDIR /app
# Copy current directory contents into /app
COPY . /app
# Install required Python packages
RUN pip install -r requirements.txt
# Command to run the Flask app via Gunicorn
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
app.py:
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello():
    # Connect to the MySQL database
    db = mysql.connector.connect(
        host="db",
        user="user",
        password="userpassword",
        database="flask_db"
    )
    return "Hello, world! This is a production-ready Flask app with MySQL and Gunicorn."
if __name__ == "__main__":
    app.run(host='0.0.0.0')
requirements.txt:
Flask
gunicorn
mysql-connector-python
nginx.conf:
server {
    listen 80;
    location / {
        proxy_pass http://web:5000;  # Proxy to the Gunicorn Flask app
    }
}
Step-by-Step Explanation:
- Web service: Flask app is served using Gunicorn, which is a production-level WSGI server.
- Nginx: Acts as a reverse proxy, forwarding HTTP requests to the Flask app running on Gunicorn.
- MySQL: A relational database service to store data, used by the Flask app.
- Command gunicorn -w 4 -b 0.0.0.0:5000 app:app: Starts the Gunicorn server with 4 worker processes, listening on port5000.
How to Deploy:
- Set up the directory structure and add the files as shown.
- Run the following command to start the application:
docker compose up --build
- Visit http://localhostto see the Flask app served via Nginx.